/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package elaborate.tag_analysis.client.utils.resource_logs;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

/**
 *
 * @author lendle
 */
public class ResourceLogHandler {

    public void save(Writer writer, ResourceLogs logs) {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc=db.newDocument();
            Element resource_log=doc.createElementNS("uTagIt", "resource-log");
            doc.appendChild(resource_log);
            for(Category category : logs.getCategories()){
                Element categoryElement=doc.createElementNS("uTagIt", "category");
                categoryElement.setAttribute("id", category.getId());
                resource_log.appendChild(categoryElement);
                for(ResourceLog resourceLog : category.getResources()){
                    Element resourceElement=doc.createElementNS("uTagIt", "resource");
                    resourceElement.setAttribute("id", resourceLog.getId());
                    resourceElement.setAttribute("status", resourceLog.getStatus().toString());
                    categoryElement.appendChild(resourceElement);
                    for(TagLog tag : resourceLog.getTags()){
                        Element tagElement=doc.createElementNS("uTagIt", "tag");
                        tagElement.setAttribute("id", tag.getId());
                        resourceElement.appendChild(tagElement);
                    }
                }
            }
            
            Transformer tf=TransformerFactory.newInstance().newTransformer();
            tf.transform(new DOMSource(doc), new StreamResult(writer));
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    public ResourceLogs load(Reader reader) {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(new InputSource(reader));
            XPath xpath = XPathFactory.newInstance().newXPath();
            ResourceLogs logs = new ResourceLogs();
            NodeList list = (NodeList) xpath.evaluate("//*[local-name()='category']", doc, XPathConstants.NODESET);
            for (int i = 0; i < list.getLength(); i++) {
                Element categoryElement = (Element) list.item(i);
                Category category = new Category();
                category.setId(categoryElement.getAttribute("id"));
                logs.getCategories().add(category);
                this.loadResourceLogList(category, categoryElement, xpath);
            }
            return logs;
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    private void loadResourceLogList(Category category, Element categoryElement, XPath xpath) throws XPathExpressionException {
        NodeList resources = (NodeList) xpath.evaluate("*[local-name()='resource']", categoryElement, XPathConstants.NODESET);
        for (int i = 0; i < resources.getLength(); i++) {
            Element resourceElement = (Element) resources.item(i);
            ResourceLog resource = new ResourceLog();
            resource.setId(resourceElement.getAttribute("id"));
            //System.out.println(resourceElement.getAttribute("status"));
            resource.setStatus(ResourceStatus.valueOf(resourceElement.getAttribute("status")));
            category.getResources().add(resource);
            this.loadTagList(resource, resourceElement, xpath);
        }
    }

    private void loadTagList(ResourceLog resource, Element resourceElement, XPath xpath) throws XPathExpressionException {
        NodeList tags = (NodeList) xpath.evaluate("*[local-name()='tag']", resourceElement, XPathConstants.NODESET);
        for (int i = 0; i < tags.getLength(); i++) {
            Element tagElement = (Element) tags.item(i);
            TagLog tag = new TagLog();
            tag.setId(tagElement.getAttribute("id"));
            resource.getTags().add(tag);
        }
    }

    public static void main(String[] args) throws Exception {
        ResourceLogHandler handler = new ResourceLogHandler();
        InputStreamReader reader = new InputStreamReader(new FileInputStream("src\\sample-resource-logs.xml"), "utf-8");
        ResourceLogs log = handler.load(reader);
        reader.close();
        
        OutputStreamWriter writer=new OutputStreamWriter(new FileOutputStream("src\\sample-resource-logs-2.xml"), "utf-8");
        handler.save(writer, log);
        writer.close();
    }
}
